package api

import (
	"context"
	"io/ioutil"
	"strconv"

	// "encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"time"

	"dev.ixmxm.top/rms/codes"
	"dev.ixmxm.top/rms/model"
	"dev.ixmxm.top/rms/utils/json"
	"dev.ixmxm.top/rms/utils/log"
	"github.com/gin-gonic/gin"
	"github.com/tealeg/xlsx"
)

// @Summary 获取所有任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.TaskTemplate "data数据：任务模板集合"
// @Tags 任务模板
// @Router /task_template/get_task_templates [get]
func (hg *HttpGateway) GetTaskTemplates(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get robot types error:%s", err.UnWrapError())
		return nil, err
	}
	return taskTemplates, nil
}

// @Summary 下载所有的模板（excel文件)
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/download_excel_task_templates [get]
func (hg *HttpGateway) DownloadExcelTaskTemplates(ctx context.Context, params interface{}, c *gin.Context) (interface{}, codes.Code) {
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get robot types error:%s", err.UnWrapError())
		return nil, err
	}
	log.Infof("", taskTemplates)
	var res []interface{}
	for _, task_template := range taskTemplates {
		res = append(res, &model.ExportTaskTemplate{
			Id:         task_template.Id,
			CategoryId: task_template.CategoryId,
			TaskType:   int(task_template.TaskType),
		})
	}
	fileName := fmt.Sprintf("%s%s.xlsx", "主任务模板", time.Now())
	// c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename*=UTF-8''%s", url.QueryEscape(fileName)))
	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	content1 := ToExcel([]string{`任务模板ID`, `AGV类型编号`, `RMS任务类型`}, res)
	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content1)
	return nil, nil
}

// @Summary 上传RMS任务模板(Excel文件)
// @Description
// @Param excel formData file true "Excel文件"
// @Produce  json
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/upload_excel_task_templates [post]
func (hg *HttpGateway) UploadExcelTaskTemplates(ctx context.Context, c *gin.Context) (interface{}, codes.Code) {
	//先读取Excel 文件
	file, _, err := c.Request.FormFile("excel")
	if file == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，未找到XML").Wrap(err)
	}
	excelBytes, err := ioutil.ReadAll(file)
	if excelBytes == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err)
	}
	xlFile, err := xlsx.OpenBinary(excelBytes)
	if err != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err)
	}

	data := ImportExcel(xlFile, 3)
	if data == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误,数据内容有误，读取失败")
	}
	//将所有的集合数据转换成对象集合
	var TaskTemplateArr []interface{}
	// var RobotTypesArr []model.RobotType
	for i := 0; i < len(data); i++ {
		var row = data[i]
		//初始化实体类
		var taskTemplate_1 model.TaskTemplate
		id, err1 := strconv.Atoi(row[0])
		categoryId, err2 := strconv.Atoi(row[1])
		taskType, err3 := strconv.Atoi(row[2])

		if err1 != nil || err2 != nil || err3 != nil {
			return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误,内容存在格式问题，读取失败")
		}
		//赋值
		taskTemplate_1.Id = id
		taskTemplate_1.CategoryId = categoryId
		taskTemplate_1.TaskType = model.TaskType(taskType)

		//添加入数组
		TaskTemplateArr = append(TaskTemplateArr, taskTemplate_1)
	}
	// //调用接口处理导入数据
	err1 := hg.dispatcher.TTM().ImportAllTaskTemplates(ctx, TaskTemplateArr)
	if err1 != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err1)
	}
	return nil, nil
}

// @Summary 上传RMS子任务模板(Excel文件)
// @Description
// @Param excel formData file true "Excel文件"
// @Produce  json
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/upload_excel_subtask_templates [post]
func (hg *HttpGateway) UploadExcelSubtaskTemplates(ctx context.Context, c *gin.Context) (interface{}, codes.Code) {
	//先读取Excel 文件
	file, _, err := c.Request.FormFile("excel")
	if file == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，未找到XML").Wrap(err)
	}
	excelBytes, err := ioutil.ReadAll(file)
	if excelBytes == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err)
	}
	xlFile, err := xlsx.OpenBinary(excelBytes)
	if err != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err)
	}
	//将xlFile文件导入，列数为8列
	data := ImportExcel(xlFile, 8)
	if data == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误,数据内容有误，读取失败")
	}
	//将所有的集合数据转换成对象集合
	var SubTaskTemplateArr []interface{}
	// var RobotTypesArr []model.RobotType
	for i := 0; i < len(data); i++ {
		var row = data[i]
		//初始化实体类
		var subTaskTemplate_1 model.TaskItemTemplate

		index, err1 := strconv.Atoi(row[0])
		taskTemplateId, err2 := strconv.Atoi(row[1])
		taskType, err3 := strconv.Atoi(row[2])
		targetType, err4 := strconv.Atoi(row[3])
		forkTemplateCmds := row[4]
		completeProcessType, err5 := strconv.Atoi(row[5])
		targetDirection, err6 := strconv.ParseInt(row[6], 10, 32)
		palletDetection, err7 := strconv.Atoi(row[7])

		if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil || err6 != nil || err7 != nil {
			return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误,内容存在格式问题，读取失败")
		}
		//将货叉指令(json数据)string->[]*ForkTemplateCmd
		forkTemplateCmdArr := &model.ForkTemplateCmdArr{}

		err9 := json.BindFromString(forkTemplateCmds, forkTemplateCmdArr)
		if err9 != nil {
			return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误,内容存在格式问题，读取失败" + err3.Error())
		}
		//将映射完的数组
		var forkTemplateArr []*model.ForkTemplateCmd
		if forkTemplateCmdArr.ForkTemplateCmdArr != nil {
			for _, forkCmd := range forkTemplateCmdArr.ForkTemplateCmdArr {
				forkTemplateArr = append(forkTemplateArr, &model.ForkTemplateCmd{
					ForkType:  model.ForkActionType(forkCmd.ForkType),
					ForkCmd:   forkCmd.ForkCmd,
					ForkValue: forkCmd.ForkValue,
				})
			}
		}
		if forkTemplateArr == nil {
			forkTemplateArr = []*model.ForkTemplateCmd{}
		}
		subTaskTemplate_1.Index = index
		subTaskTemplate_1.TaskTemplateId = taskTemplateId
		subTaskTemplate_1.TaskType = model.TaskType(taskType)
		subTaskTemplate_1.TargetType = model.TaskTemplateTargetType(targetType)
		subTaskTemplate_1.ForkTemplateCmds = forkTemplateArr
		subTaskTemplate_1.CompleteProcessType = model.CompleteProcessType(completeProcessType)
		subTaskTemplate_1.TargetDirection = int32(targetDirection)
		subTaskTemplate_1.PalletDetection = model.PalletDetectionType(palletDetection)

		//添加入数组
		SubTaskTemplateArr = append(SubTaskTemplateArr, subTaskTemplate_1)
	}
	// log.Infof("即将上传的子任务模板数据：", &SubTaskTemplateArr)
	// //调用接口处理导入数据
	err1 := hg.dispatcher.TTM().ImportAllSubtaskTemplates(ctx, SubTaskTemplateArr)
	if err1 != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("Excel文件传入有误，读取失败").Wrap(err1)
	}
	return nil, nil
}

// @Summary 获取任务模板所有子模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param task_template_id query int true "任务模板ID"
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.TaskItemTemplate "data数据：子任务模板集合"
// @Tags 任务模板
// @Router /task_template/get_subtask_templates [get]
func (hg *HttpGateway) GetSubtaskTemplates(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*getSubtaskTemplateParams)
	taskItemTemplates, err := hg.dispatcher.TTM().GetTaskItemTemplates(ctx, p.TaskTemplateId)
	if err != nil {
		log.ErrorfWithContext(ctx, "get robot types error:%s", err.UnWrapError())
		return nil, err
	}
	return taskItemTemplates, nil
}

// @Summary 下载所有的子模板(excel文件)
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/download_excel_subtask_templates [get]
func (hg *HttpGateway) DownloadExcelSubTaskTemplates(ctx context.Context, params interface{}, c *gin.Context) (interface{}, codes.Code) {
	taskItemTemplates, err := hg.dispatcher.TTM().GetTaskExportItemTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get robot types error:%s", err.UnWrapError())
		return nil, err
	}
	log.Infof("", taskItemTemplates)
	var res []interface{}
	for _, task_item_templates := range taskItemTemplates {
		//先提前获得所有的货叉数组
		var forkTemplateCmds []*model.ForkExportTemplateCmd
		for _, forkCmd := range task_item_templates.ForkTemplateCmds {
			forkTemplateCmds = append(forkTemplateCmds, &model.ForkExportTemplateCmd{
				ForkType:  int(forkCmd.ForkType),
				ForkCmd:   forkCmd.ForkCmd,
				ForkValue: forkCmd.ForkValue,
			})
		}
		arr := &model.ForkTemplateCmdArr{}
		arr.ForkTemplateCmdArr = forkTemplateCmds
		arr2 := json.DumpString(arr)

		res = append(res, &model.TaskItemExportTemplate{
			Index:               task_item_templates.Index,
			TaskTemplateId:      task_item_templates.TaskTemplateId,
			TaskType:            int(task_item_templates.TaskType),
			TargetType:          int(task_item_templates.TargetType),
			ForkTemplateCmds:    arr2,
			CompleteProcessType: int(task_item_templates.CompleteProcessType),
			TargetDirection:     task_item_templates.TargetDirection,
			PalletDetection:     int(task_item_templates.PalletDetection),
		})
	}
	fileName := fmt.Sprintf("%s%s.xlsx", "子模板数据", time.Now())
	// c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename*=UTF-8''%s", url.QueryEscape(fileName)))
	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	content1 := ToExcel([]string{`索引`, `主任务模板ID`, `RMS任务类型`, `目标点类型`, `货叉指令集合`, `完成处理类型`, `目标货叉方向`, `货叉检测货物类型`}, res)
	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content1)
	return nil, nil
}

// @Summary 添加任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body model.TaskTemplate true "任务模板"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/add_task_template [post]
func (hg *HttpGateway) AddTaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*SaveTaskTemplateParams)
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	if p.Id < 1 {
		return nil, codes.ErrTemplateNotMatch.WithDetails("该任务模板ID需要大于0")
	}
	for _, taskTemplate := range taskTemplates {
		if taskTemplate.Id == p.Id {
			return nil, codes.ErrTemplateNotMatch.WithDetails("该任务模板ID已存在，不可重复")
		}
		if taskTemplate.CategoryId == p.CategoryId && taskTemplate.TaskType == p.TaskType {
			return nil, codes.ErrTemplateNotMatch.WithDetails("该任务模板小车类型编号和任务类型已存在，不可重复")
		}
	}
	return nil, hg.dispatcher.TTM().SaveTaskTemplate(ctx, &p.TaskTemplate)
}

// @Summary 保存任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body model.TaskTemplate true "任务模板"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/save_task_template [post]
func (hg *HttpGateway) SaveTaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*SaveTaskTemplateParams)
	if p.Id < 1 {
		return nil, codes.ErrTemplateNotMatch.WithDetails("该任务模板ID需要大于0")
	}
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	isAny := false
	for _, taskTemplate := range taskTemplates {
		if taskTemplate.Id == p.Id {
			isAny = true
		}
		if taskTemplate.Id != p.Id && taskTemplate.CategoryId == p.CategoryId && taskTemplate.TaskType == p.TaskType {
			return nil, codes.ErrTemplateNotMatch.WithDetails("该任务模板小车类型编号和任务类型已存在，不可重复")
		}
	}
	if !isAny {
		return nil, codes.ErrTemplateNotExists
	}
	return nil, hg.dispatcher.TTM().SaveTaskTemplate(ctx, &p.TaskTemplate)
}

// @Summary 添加子任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body model.TaskItemTemplate true "子任务模板"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/add_subtask_template [post]
func (hg *HttpGateway) AddSubtaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*SaveSubtaskTemplateParams)
	if p.Index < 1 {
		return nil, codes.ErrTemplateNotMatch.WithDetails("该子任务模板索引需要大于0")
	}
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	isAny := false
	for _, taskTemplate := range taskTemplates {
		if taskTemplate.Id == p.TaskTemplateId {
			isAny = true
		}
	}
	if !isAny {
		return nil, codes.ErrTemplateNotExists
	}
	taskItemTemplates, err := hg.dispatcher.TTM().GetTaskItemTemplates(ctx, p.TaskTemplateId)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取子任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	for _, subtaskTemplate := range taskItemTemplates {
		if subtaskTemplate.Index == p.Index {
			return nil, codes.ErrTemplateNotMatch.WithDetails("该子任务模板索引已存在，不可重复")
		}
	}
	return nil, hg.dispatcher.TTM().SaveTaskItemTemplate(ctx, &p.TaskItemTemplate)
}

// @Summary 批量添加子任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body SaveSubtaskTemplateListParams true "子任务模板数组"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/add_subtask_template_list [post]
func (hg *HttpGateway) AddSubtaskTemplateList(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*SaveSubtaskTemplateListParams)
	return nil, hg.dispatcher.TTM().SaveTaskItemTemplateList(ctx, p.SubTaskTemplateList, p.TaskTemplateId)
}

// @Summary 保存子任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body model.TaskItemTemplate true "子任务模板"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/save_subtask_template [post]
func (hg *HttpGateway) SaveSubtaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*SaveSubtaskTemplateParams)
	if p.Index < 1 {
		return nil, codes.ErrTemplateNotMatch.WithDetails("该子任务模板索引需要大于0")
	}
	taskTemplates, err := hg.dispatcher.TTM().GetAllTaskTemplates(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	isAny := false
	for _, taskTemplate := range taskTemplates {
		if taskTemplate.Id == p.TaskTemplateId {
			isAny = true
		}
	}
	if !isAny {
		return nil, codes.ErrTemplateNotExists.WithDetails("任务模板索引不存在")
	}
	taskItemTemplates, err := hg.dispatcher.TTM().GetTaskItemTemplates(ctx, p.TaskTemplateId)
	if err != nil {
		log.ErrorfWithContext(ctx, "获取子任务模板失败 error:%s", err.UnWrapError())
		return nil, err
	}
	isAny = false
	for _, subtaskTemplate := range taskItemTemplates {
		if subtaskTemplate.Index == p.Index {
			isAny = true
		}
	}
	if !isAny {
		return nil, codes.ErrTemplateNotExists.WithDetails("子任务模板索引不存在")
	}
	return nil, hg.dispatcher.TTM().SaveTaskItemTemplate(ctx, &p.TaskItemTemplate)
}

// @Summary 删除任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param id query int true "任务模板ID"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/delete_task_template [delete]
func (hg *HttpGateway) DeleteTaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*DeleteTaskTemplateParams)
	return nil, hg.dispatcher.TTM().DeleteTaskTemplate(ctx, p.Id)
}

// @Summary 删除子任务模板
// @Description
// @Accept application/json
// @Produce application/json
// @Param task_template_id query int true "任务模板ID"
// @Param index query int true "子任务模板索引"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 任务模板
// @Router /task_template/delete_subtask_template [delete]
func (hg *HttpGateway) DeleteSubtaskTemplate(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*DeleteSubtaskTemplateParams)
	return nil, hg.dispatcher.TTM().DeleteTaskItemTemplate(ctx, p.TaskTemplateId, p.Index)
}
